#include <CpLog.h>
#include "CpPolynom2D.h"
#include <TMath.h>

ClassImp(CpPolynom2D);

//______________________________________________________________________________
CpPolynom2D::CpPolynom2D(): TObject()
{
//
// Constructor
//

   CpDebug(CpLog::kDebug + 5, "<-");
   CpDebug(CpLog::kDebug + 5, "->");

}

//______________________________________________________________________________
CpPolynom2D::~CpPolynom2D()
{
//
// Destructor.
//
   CpDebug(CpLog::kDebug + 5, "<-");
   CpDebug(CpLog::kDebug + 5, "->");
}


//______________________________________________________________________________
Int_t CpPolynom2D::GetNumberOfParameters(Int_t grade)
{
//
// Gets Number of parameters
//
//     CpDebug(CpLog::kDebug+5,"<-");
   switch (grade) {
      case 0:
         return 1;
      case 1:
         return 3;
      case 2:
         return 6;
      case 3:
         return 10;
      case 4:
         return 15;
      case 5:
         return 21;
      case 6:
         return 28;
      case 7:
         return 36;
      case 8:
         return 45;
      case 9:
         return 55;
      case 10:
         return 66;
//     case 11: return 12;
      default :
         return -1;

   }

//     CpDebug(CpLog::kDebug+5,"->");
}


Double_t CpPolynom2D::Degree0(Double_t *x, Double_t *par)
{
   Double_t r = par[0] + x[0] * 0;
   return r;
}


Double_t CpPolynom2D::Degree1(Double_t *x, Double_t *par)
{

   Double_t r = Degree0(x, par);;
   r += par[1] * TMath::Power(x[0], 1);
   r += par[2] * TMath::Power(x[1], 1);
   return r;
}


Double_t CpPolynom2D::Degree2(Double_t *x, Double_t *par)
{
   Double_t r = Degree1(x, par);
   // x^2 y^2
   r += par[3] * TMath::Power(x[0], 2);
   r += par[4] * TMath::Power(x[1], 2);
   r += par[5] * TMath::Power(x[0], 1) * TMath::Power(x[1], 1);
   return r;
}


Double_t CpPolynom2D::Degree3(Double_t *x, Double_t *par)
{
   Double_t r = Degree2(x, par);
   // x^3 y^3 x^2*y x*y^2 x*y^3
   r += par[6] * TMath::Power(x[0], 3);
   r += par[7] * TMath::Power(x[1], 3);
   r += par[8] * TMath::Power(x[0], 2) * TMath::Power(x[1], 1);
   r += par[9] * TMath::Power(x[0], 1) * TMath::Power(x[1], 2);

   return r;
}

Double_t CpPolynom2D::Degree4(Double_t *x, Double_t *par)
{
   Double_t r = Degree3(x, par);;
   // x^4 y^4 x^3*y x^2*y^2 x*y^3
   r += par[10] * TMath::Power(x[0], 4);
   r += par[11] * TMath::Power(x[1], 4);
   r += par[12] * TMath::Power(x[0], 3) * TMath::Power(x[1], 1);
   r += par[13] * TMath::Power(x[0], 2) * TMath::Power(x[1], 2);
   r += par[14] * TMath::Power(x[0], 1) * TMath::Power(x[1], 3);
   return r;
}


Double_t CpPolynom2D::Degree5(Double_t *x, Double_t *par)
{
   Double_t r = Degree4(x, par);;
// x^5 y^5 x^4*y x^3*y^2 x^2*y^3 x*y^4
   r += par[15] * TMath::Power(x[0], 5);
   r += par[16] * TMath::Power(x[1], 5);
   r += par[17] * TMath::Power(x[0], 4) * TMath::Power(x[1], 1);
   r += par[18] * TMath::Power(x[0], 3) * TMath::Power(x[1], 2);
   r += par[19] * TMath::Power(x[0], 2) * TMath::Power(x[1], 3);
   r += par[20] * TMath::Power(x[0], 1) * TMath::Power(x[1], 4);
   return r;
}

Double_t CpPolynom2D::Degree6(Double_t *x, Double_t *par)
{
   Double_t r = Degree5(x, par);;
   // x^6 y^6 x^5*y x^4*y^2 x^3*y^3 x^2*y^4 x*y^5
   r += par[21] * TMath::Power(x[0], 6);
   r += par[22] * TMath::Power(x[1], 6);
   r += par[23] * TMath::Power(x[0], 5) * TMath::Power(x[1], 1);
   r += par[24] * TMath::Power(x[0], 4) * TMath::Power(x[1], 2);
   r += par[25] * TMath::Power(x[0], 3) * TMath::Power(x[1], 3);
   r += par[26] * TMath::Power(x[0], 2) * TMath::Power(x[1], 4);
   r += par[27] * TMath::Power(x[0], 1) * TMath::Power(x[1], 5);
   return r;
}

Double_t CpPolynom2D::Degree7(Double_t *x, Double_t *par)
{
   Double_t r = Degree6(x, par);;
   // x^7 y^7 x^6*y x^5*y^2 x^4*y^3 x^3*y^4 x^2*y^5 x*y^6
   r += par[28] * TMath::Power(x[0], 7);
   r += par[29] * TMath::Power(x[1], 7);
   r += par[30] * TMath::Power(x[0], 6) * TMath::Power(x[1], 1);
   r += par[31] * TMath::Power(x[0], 5) * TMath::Power(x[1], 2);
   r += par[32] * TMath::Power(x[0], 4) * TMath::Power(x[1], 3);
   r += par[33] * TMath::Power(x[0], 3) * TMath::Power(x[1], 4);
   r += par[34] * TMath::Power(x[0], 2) * TMath::Power(x[1], 5);
   r += par[35] * TMath::Power(x[0], 1) * TMath::Power(x[1], 6);
   return r;
}


Double_t CpPolynom2D::Degree8(Double_t *x, Double_t *par)
{
   Double_t r = Degree7(x, par);;
   // x^8 y^8 x^7*y x^6*y^2 x^5*y^3 x^4*y^4 x^3*y^5 x^2*y^6 x*y^7
   r += par[36] * TMath::Power(x[0], 8);
   r += par[37] * TMath::Power(x[1], 8);
   r += par[38] * TMath::Power(x[0], 7) * TMath::Power(x[1], 1);
   r += par[39] * TMath::Power(x[0], 6) * TMath::Power(x[1], 2);
   r += par[40] * TMath::Power(x[0], 5) * TMath::Power(x[1], 3);
   r += par[41] * TMath::Power(x[0], 4) * TMath::Power(x[1], 4);
   r += par[42] * TMath::Power(x[0], 3) * TMath::Power(x[1], 5);
   r += par[43] * TMath::Power(x[0], 2) * TMath::Power(x[1], 6);
   r += par[44] * TMath::Power(x[0], 1) * TMath::Power(x[1], 7);
   return r;
}


Double_t CpPolynom2D::Degree9(Double_t *x, Double_t *par)
{
   Double_t r = Degree8(x, par);;
   // x^9 y^9 x^8*y x^7*y^2 x^6*y^3 x^5*y^4 x^4*y^5 x^3*y^6 x^2*y^7 x*y^8
   r += par[45] * TMath::Power(x[0], 9);
   r += par[46] * TMath::Power(x[1], 9);
   r += par[47] * TMath::Power(x[0], 8) * TMath::Power(x[1], 1);
   r += par[48] * TMath::Power(x[0], 7) * TMath::Power(x[1], 2);
   r += par[49] * TMath::Power(x[0], 6) * TMath::Power(x[1], 3);
   r += par[50] * TMath::Power(x[0], 5) * TMath::Power(x[1], 4);
   r += par[51] * TMath::Power(x[0], 4) * TMath::Power(x[1], 5);
   r += par[52] * TMath::Power(x[0], 3) * TMath::Power(x[1], 6);
   r += par[53] * TMath::Power(x[0], 2) * TMath::Power(x[1], 7);
   r += par[54] * TMath::Power(x[0], 1) * TMath::Power(x[1], 8);
   return r;
}
Double_t CpPolynom2D::Degree10(Double_t *x, Double_t *par)
{
   Double_t r = Degree9(x, par);;
   // x^10 y^10 x^9*y x^8*y^2 x^7*y^3 x^6*y^4 x^5*y^5 x^4*y^6 x^3*y^7 x^2*y^8 x*y^9
   r += par[55] * TMath::Power(x[0], 10);
   r += par[56] * TMath::Power(x[1], 10);
   r += par[57] * TMath::Power(x[0], 9) * TMath::Power(x[1], 1);
   r += par[58] * TMath::Power(x[0], 8) * TMath::Power(x[1], 2);
   r += par[59] * TMath::Power(x[0], 7) * TMath::Power(x[1], 3);
   r += par[60] * TMath::Power(x[0], 6) * TMath::Power(x[1], 4);
   r += par[61] * TMath::Power(x[0], 5) * TMath::Power(x[1], 5);
   r += par[62] * TMath::Power(x[0], 4) * TMath::Power(x[1], 6);
   r += par[63] * TMath::Power(x[0], 3) * TMath::Power(x[1], 7);
   r += par[64] * TMath::Power(x[0], 2) * TMath::Power(x[1], 8);
   r += par[65] * TMath::Power(x[0], 1) * TMath::Power(x[1], 9);
   return r;
}


// Derivacia podla x

Double_t CpPolynom2D::DerivateXDegree0(Double_t */*x*/, Double_t */*par*/)
{
   return 0;
}


Double_t CpPolynom2D::DerivateXDegree1(Double_t *x, Double_t *par)
{

   Double_t r = DerivateXDegree0(x, par);
   r += par[1];
//    r += par[2] * TMath::Power(x[1], 1);
   return r;
}


Double_t CpPolynom2D::DerivateXDegree2(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree1(x, par);
   // x^2 y^2
   r += 2 * par[3] * TMath::Power(x[0], 1);
//    r += par[4] * TMath::Power(x[1], 2);
   r += par[5] * TMath::Power(x[1], 1);
   return r;
}


Double_t CpPolynom2D::DerivateXDegree3(Double_t *x, Double_t *par)
{ 
   Double_t r = DerivateXDegree2(x, par);
   // x^3 y^3 x^2*y x*y^2 x*y^3
   r += 3 * par[6] * TMath::Power(x[0], 2);
   // r += par[7] * TMath::Power(x[1], 3);
   r += 2 * par[8] * TMath::Power(x[0], 1)* TMath::Power(x[1], 1);
   r += par[9] * TMath::Power(x[1], 2);

   return r;
}

Double_t CpPolynom2D::DerivateXDegree4(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree3(x, par);;
   // x^4 y^4 x^3*y x^2*y^2 x*y^3
   r += 4 * par[10] * TMath::Power(x[0], 3);
   // r += par[11] * TMath::Power(x[1], 4);
   r += 3 * par[12] * TMath::Power(x[0], 2) * TMath::Power(x[1], 1);
   r += 2 * par[13] * TMath::Power(x[0], 1) * TMath::Power(x[1], 2);
   r += par[14] * TMath::Power(x[1], 3);
   return r;
}

Double_t CpPolynom2D::DerivateXDegree5(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree4(x, par);;
// x^5 y^5 x^4*y x^3*y^2 x^2*y^3 x*y^4
   r += 5 * par[15] * TMath::Power(x[0], 4);
   // r += par[16] * TMath::Power(x[1], 5);
   r += 4 * par[17] * TMath::Power(x[0], 3) * TMath::Power(x[1], 1);
   r += 3 * par[18] * TMath::Power(x[0], 2) * TMath::Power(x[1], 2);
   r += 2 * par[19] * TMath::Power(x[0], 1) * TMath::Power(x[1], 3);
   r += par[20] * TMath::Power(x[1], 4);
   return r;
}

Double_t CpPolynom2D::DerivateXDegree6(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree5(x, par);;
   // x^6 y^6 x^5*y x^4*y^2 x^3*y^3 x^2*y^4 x*y^5
   r += 6 * par[21] * TMath::Power(x[0], 5);
   //r += par[22] * TMath::Power(x[1], 6);
   r += 5 * par[23] * TMath::Power(x[0], 4) * TMath::Power(x[1], 1);
   r += 4 * par[24] * TMath::Power(x[0], 3) * TMath::Power(x[1], 2);
   r += 3 * par[25] * TMath::Power(x[0], 2) * TMath::Power(x[1], 3);
   r += 2 * par[26] * TMath::Power(x[0], 1) * TMath::Power(x[1], 4);
   r += par[27] * TMath::Power(x[1], 5);
   return r;
}

Double_t CpPolynom2D::DerivateXDegree7(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree6(x, par);;
   // x^7 y^7 x^6*y x^5*y^2 x^4*y^3 x^3*y^4 x^2*y^5 x*y^6
   r += 7 * par[28] * TMath::Power(x[0], 6);
   // r += par[29] * TMath::Power(x[1], 7);
   r += 6 * par[30] * TMath::Power(x[0], 5) * TMath::Power(x[1], 1);
   r += 5 * par[31] * TMath::Power(x[0], 4) * TMath::Power(x[1], 2);
   r += 4 * par[32] * TMath::Power(x[0], 3) * TMath::Power(x[1], 3);
   r += 3 * par[33] * TMath::Power(x[0], 2) * TMath::Power(x[1], 4);
   r += 2 * par[34] * TMath::Power(x[0], 1) * TMath::Power(x[1], 5);
   r += par[35] * TMath::Power(x[1], 6);
   return r;
}


Double_t CpPolynom2D::DerivateXDegree8(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree7(x, par);;
   // x^8 y^8 x^7*y x^6*y^2 x^5*y^3 x^4*y^4 x^3*y^5 x^2*y^6 x*y^7
   r += 8 * par[36] * TMath::Power(x[0], 7);
   // r += par[37] * TMath::Power(x[1], 8);
   r += 7 * par[38] * TMath::Power(x[0], 6) * TMath::Power(x[1], 1);
   r += 6 * par[39] * TMath::Power(x[0], 5) * TMath::Power(x[1], 2);
   r += 5 * par[40] * TMath::Power(x[0], 4) * TMath::Power(x[1], 3);
   r += 4 * par[41] * TMath::Power(x[0], 3) * TMath::Power(x[1], 4);
   r += 3 * par[42] * TMath::Power(x[0], 2) * TMath::Power(x[1], 5);
   r += 2 * par[43] * TMath::Power(x[0], 1) * TMath::Power(x[1], 6);
   r += par[44] * TMath::Power(x[1], 7);
   return r;
}


Double_t CpPolynom2D::DerivateXDegree9(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree8(x, par);;
   // x^9 y^9 x^8*y x^7*y^2 x^6*y^3 x^5*y^4 x^4*y^5 x^3*y^6 x^2*y^7 x*y^8
   r += 9 * par[45] * TMath::Power(x[0], 8);
   // r += par[46] * TMath::Power(x[1], 9);
   r += 8 * par[47] * TMath::Power(x[0], 7) * TMath::Power(x[1], 1);
   r += 7 * par[48] * TMath::Power(x[0], 6) * TMath::Power(x[1], 2);
   r += 6 * par[49] * TMath::Power(x[0], 5) * TMath::Power(x[1], 3);
   r += 5 * par[50] * TMath::Power(x[0], 4) * TMath::Power(x[1], 4);
   r += 4 * par[51] * TMath::Power(x[0], 3) * TMath::Power(x[1], 5);
   r += 3 * par[52] * TMath::Power(x[0], 2) * TMath::Power(x[1], 6);
   r += 2 * par[53] * TMath::Power(x[0], 1) * TMath::Power(x[1], 7);
   r += par[54] * TMath::Power(x[1], 8);
   return r;
}
Double_t CpPolynom2D::DerivateXDegree10(Double_t *x, Double_t *par)
{
   Double_t r = DerivateXDegree9(x, par);;
   // x^10 y^10 x^9*y x^8*y^2 x^7*y^3 x^6*y^4 x^5*y^5 x^4*y^6 x^3*y^7 x^2*y^8 x*y^9
   r += 10 * par[55] * TMath::Power(x[0], 9);
   // r += par[56] * TMath::Power(x[1], 10);
   r += 9 * par[57] * TMath::Power(x[0], 8) * TMath::Power(x[1], 1);
   r += 8 * par[58] * TMath::Power(x[0], 7) * TMath::Power(x[1], 2);
   r += 7 * par[59] * TMath::Power(x[0], 6) * TMath::Power(x[1], 3);
   r += 6 * par[60] * TMath::Power(x[0], 5) * TMath::Power(x[1], 4);
   r += 5 * par[61] * TMath::Power(x[0], 4) * TMath::Power(x[1], 5);
   r += 4 * par[62] * TMath::Power(x[0], 3) * TMath::Power(x[1], 6);
   r += 3 * par[63] * TMath::Power(x[0], 2) * TMath::Power(x[1], 7);
   r += 2 * par[64] * TMath::Power(x[0], 1) * TMath::Power(x[1], 8);
   r += par[65] * TMath::Power(x[1], 9);
   return r;
}

// Derivacia podla y
Double_t CpPolynom2D::DerivateYDegree0(Double_t */*x*/, Double_t */*par*/)
{
   return 0;
}


Double_t CpPolynom2D::DerivateYDegree1(Double_t *x, Double_t *par)
{

   Double_t r = DerivateYDegree0(x, par);;
   // r += par[1] * TMath::Power(x[0], 1);
   r += par[2];
   return r;
}


Double_t CpPolynom2D::DerivateYDegree2(Double_t *x, Double_t *par)
{
   Double_t r = DerivateYDegree1(x, par);
   // x^2 y^2
   // r += par[3] * TMath::Power(x[0], 2);
   r += 2 * par[4] * TMath::Power(x[1], 1);
   r += par[5] * TMath::Power(x[0], 1);
   return r;
}


Double_t CpPolynom2D::DerivateYDegree3(Double_t *x, Double_t *par)
{
   Double_t r = DerivateYDegree2(x, par);
   // x^3 y^3 x^2*y x*y^2 x*y^3
   // r += par[6] * TMath::Power(x[0], 3);
   r += 3 * par[7] * TMath::Power(x[1], 2);
   r += par[8] * TMath::Power(x[0], 2);
   r += 2 * par[9] * TMath::Power(x[0], 1) * TMath::Power(x[1], 1);

   return r;
}

Double_t CpPolynom2D::DerivateYDegree4(Double_t *x, Double_t *par)
{
   Double_t r = DerivateYDegree3(x, par);;
   // x^4 y^4 x^3*y x^2*y^2 x*y^3
   // r += par[10] * TMath::Power(x[0], 4);
   r += 4 * par[11] * TMath::Power(x[1], 3);
   r += par[12] * TMath::Power(x[0], 3);
   r += 2 * par[13] * TMath::Power(x[0], 2) * TMath::Power(x[1], 1);
   r += 3 * par[14] * TMath::Power(x[0], 1) * TMath::Power(x[1], 2);
   return r;
}


Double_t CpPolynom2D::DerivateYDegree5(Double_t *x, Double_t *par)
{
   Double_t r = DerivateYDegree4(x, par);;
// x^5 y^5 x^4*y x^3*y^2 x^2*y^3 x*y^4
   // r += par[15] * TMath::Power(x[0], 5);
   r += 5 * par[16] * TMath::Power(x[1], 4);
   r += par[17] * TMath::Power(x[0], 4) ;
   r += 2 * par[18] * TMath::Power(x[0], 3) * TMath::Power(x[1], 1);
   r += 3 * par[19] * TMath::Power(x[0], 2) * TMath::Power(x[1], 2);
   r += 4 * par[20] * TMath::Power(x[0], 1) * TMath::Power(x[1], 3);
   return r;
}

Double_t CpPolynom2D::DerivateYDegree6(Double_t *x, Double_t *par)
{
   Double_t r = DerivateYDegree5(x, par);;
   // x^6 y^6 x^5*y x^4*y^2 x^3*y^3 x^2*y^4 x*y^5
   // r += par[21] * TMath::Power(x[0], 6);
   r +=6 * par[22] * TMath::Power(x[1], 5);
   r += par[23] * TMath::Power(x[0], 5);
   r += 2 * par[24] * TMath::Power(x[0], 4) * TMath::Power(x[1], 1);
   r += 3 * par[25] * TMath::Power(x[0], 3) * TMath::Power(x[1], 2);
   r += 4 * par[26] * TMath::Power(x[0], 2) * TMath::Power(x[1], 3);
   r += 5 * par[27] * TMath::Power(x[0], 1) * TMath::Power(x[1], 4);
   return r;
}

Double_t CpPolynom2D::DerivateYDegree7(Double_t *x, Double_t *par)
{
   Double_t r = DerivateYDegree6(x, par);;
   // x^7 y^7 x^6*y x^5*y^2 x^4*y^3 x^3*y^4 x^2*y^5 x*y^6
   // r += par[28] * TMath::Power(x[0], 7);
   r += 7 * par[29] * TMath::Power(x[1], 6);
   r += par[30] * TMath::Power(x[0], 6) ;
   r += 2 * par[31] * TMath::Power(x[0], 5) * TMath::Power(x[1], 1);
   r += 3 * par[32] * TMath::Power(x[0], 4) * TMath::Power(x[1], 2);
   r += 4 * par[33] * TMath::Power(x[0], 3) * TMath::Power(x[1], 3);
   r += 5 * par[34] * TMath::Power(x[0], 2) * TMath::Power(x[1], 4);
   r += 6 * par[35] * TMath::Power(x[0], 1) * TMath::Power(x[1], 5);
   return r;
}


Double_t CpPolynom2D::DerivateYDegree8(Double_t *x, Double_t *par)
{
   Double_t r = DerivateYDegree7(x, par);;
   // x^8 y^8 x^7*y x^6*y^2 x^5*y^3 x^4*y^4 x^3*y^5 x^2*y^6 x*y^7
   // r += par[36] * TMath::Power(x[0], 8);
   r += 8 * par[37] * TMath::Power(x[1], 7);
   r += par[38] * TMath::Power(x[0], 7) ;
   r += 2 * par[39] * TMath::Power(x[0], 6) * TMath::Power(x[1], 1);
   r += 3 * par[40] * TMath::Power(x[0], 5) * TMath::Power(x[1], 2);
   r += 4 * par[41] * TMath::Power(x[0], 4) * TMath::Power(x[1], 3);
   r += 5 * par[42] * TMath::Power(x[0], 3) * TMath::Power(x[1], 4);
   r += 6 * par[43] * TMath::Power(x[0], 2) * TMath::Power(x[1], 5);
   r += 7 * par[44] * TMath::Power(x[0], 1) * TMath::Power(x[1], 6);
   return r;
}


Double_t CpPolynom2D::DerivateYDegree9(Double_t *x, Double_t *par)
{
   Double_t r = DerivateYDegree8(x, par);;
   // x^9 y^9 x^8*y x^7*y^2 x^6*y^3 x^5*y^4 x^4*y^5 x^3*y^6 x^2*y^7 x*y^8
   // r += par[45] * TMath::Power(x[0], 9);
   r += 9 * par[46] * TMath::Power(x[1], 8);
   r += par[47] * TMath::Power(x[0], 8) ;
   r += 2 * par[48] * TMath::Power(x[0], 7) * TMath::Power(x[1], 1);
   r += 3 * par[49] * TMath::Power(x[0], 6) * TMath::Power(x[1], 2);
   r += 4 * par[50] * TMath::Power(x[0], 5) * TMath::Power(x[1], 3);
   r += 5 * par[51] * TMath::Power(x[0], 4) * TMath::Power(x[1], 4);
   r += 6 * par[52] * TMath::Power(x[0], 3) * TMath::Power(x[1], 5);
   r += 7 * par[53] * TMath::Power(x[0], 2) * TMath::Power(x[1], 6);
   r += 8 * par[54] * TMath::Power(x[0], 1) * TMath::Power(x[1], 7);
   return r;
}
Double_t CpPolynom2D::DerivateYDegree10(Double_t *x, Double_t *par)
{
   Double_t r = DerivateYDegree9(x, par);;
   // x^10 y^10 x^9*y x^8*y^2 x^7*y^3 x^6*y^4 x^5*y^5 x^4*y^6 x^3*y^7 x^2*y^8 x*y^9
   // r += par[55] * TMath::Power(x[0], 10);
   r += 10 * par[56] * TMath::Power(x[1], 9);
   r += par[57] * TMath::Power(x[0], 9) ;
   r += 2 * par[58] * TMath::Power(x[0], 8) * TMath::Power(x[1], 1);
   r += 3 * par[59] * TMath::Power(x[0], 7) * TMath::Power(x[1], 2);
   r += 4 * par[60] * TMath::Power(x[0], 6) * TMath::Power(x[1], 3);
   r += 5 * par[61] * TMath::Power(x[0], 5) * TMath::Power(x[1], 4);
   r += 6 * par[62] * TMath::Power(x[0], 4) * TMath::Power(x[1], 5);
   r += 7 * par[63] * TMath::Power(x[0], 3) * TMath::Power(x[1], 6);
   r += 8 * par[64] * TMath::Power(x[0], 2) * TMath::Power(x[1], 7);
   r += 9 * par[65] * TMath::Power(x[0], 1) * TMath::Power(x[1], 8);
   return r;
}

// 2 Derivacia podla x

Double_t CpPolynom2D::Derivate2XDegree0(Double_t */*x*/, Double_t */*par*/)
{
   return 0;
}


Double_t CpPolynom2D::Derivate2XDegree1(Double_t */*x*/, Double_t */*par*/)
{

  // Double_t r = Derivate2XDegree0(x, par);
 //  r += par[1];
//    r += par[2] * TMath::Power(x[1], 1);
   return 0;
}


Double_t CpPolynom2D::Derivate2XDegree2(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree1(x, par);
   // x^2 y^2
   r += 2 * par[3];
//    r += par[4] * TMath::Power(x[1], 2);
//   r += par[5] * TMath::Power(x[1], 1);
   return r;
}


Double_t CpPolynom2D::Derivate2XDegree3(Double_t *x, Double_t *par)
{ 
   Double_t r = Derivate2XDegree2(x, par);
   // x^3 y^3 x^2*y x*y^2 x*y^3
   r += 6 * par[6] * TMath::Power(x[0], 1);
   // r += par[7] * TMath::Power(x[1], 3);
   r += 2 * par[8] * TMath::Power(x[1], 1);
   r += 2 * par[9] * TMath::Power(x[1], 1);

   return r;
}

Double_t CpPolynom2D::Derivate2XDegree4(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree3(x, par);;
   // x^4 y^4 x^3*y x^2*y^2 x*y^3
   r += 12 * par[10] * TMath::Power(x[0], 2);
   // r += par[11] * TMath::Power(x[1], 4);
   r += 6 * par[12] * TMath::Power(x[0], 1) * TMath::Power(x[1], 1);
   r += 2 * par[13] * TMath::Power(x[1], 2);
   // r += par[14] * TMath::Power(x[1], 3);
   return r;
}


Double_t CpPolynom2D::Derivate2XDegree5(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree4(x, par);;
// x^5 y^5 x^4*y x^3*y^2 x^2*y^3 x*y^4
   r += 20 * par[15] * TMath::Power(x[0], 3);
   // r += par[16] * TMath::Power(x[1], 5);
   r += 12 * par[17] * TMath::Power(x[0], 2) * TMath::Power(x[1], 1);
   r += 6 * par[18] * TMath::Power(x[0], 1) * TMath::Power(x[1], 2);
   r += 2 * par[19] * TMath::Power(x[1], 3);
  // r += par[20] * TMath::Power(x[1], 4);
   return r;
}

Double_t CpPolynom2D::Derivate2XDegree6(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree5(x, par);;
   // x^6 y^6 x^5*y x^4*y^2 x^3*y^3 x^2*y^4 x*y^5
   r += 30 * par[21] * TMath::Power(x[0], 4);
   //r += par[22] * TMath::Power(x[1], 6);
   r += 20 * par[23] * TMath::Power(x[0], 3) * TMath::Power(x[1], 1);
   r += 12 * par[24] * TMath::Power(x[0], 2) * TMath::Power(x[1], 2);
   r += 6 * par[25] * TMath::Power(x[0], 1) * TMath::Power(x[1], 3);
   r += 2 * par[26]  * TMath::Power(x[1], 4);
  //  r += par[27] * TMath::Power(x[1], 5);
   return r;
}

Double_t CpPolynom2D::Derivate2XDegree7(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree6(x, par);;
   // x^7 y^7 x^6*y x^5*y^2 x^4*y^3 x^3*y^4 x^2*y^5 x*y^6
   r += 42 * par[28] * TMath::Power(x[0], 5);
   // r += par[29] * TMath::Power(x[1], 7);
   r += 30 * par[30] * TMath::Power(x[0], 4) * TMath::Power(x[1], 1);
   r += 20 * par[31] * TMath::Power(x[0], 3) * TMath::Power(x[1], 2);
   r += 12 * par[32] * TMath::Power(x[0], 2) * TMath::Power(x[1], 3);
   r += 6 * par[33] * TMath::Power(x[0], 1) * TMath::Power(x[1], 4);
   r += 2 * par[34]  * TMath::Power(x[1], 5);
   // r += par[35] * TMath::Power(x[1], 6);
   return r;
}


Double_t CpPolynom2D::Derivate2XDegree8(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree7(x, par);;
   // x^8 y^8 x^7*y x^6*y^2 x^5*y^3 x^4*y^4 x^3*y^5 x^2*y^6 x*y^7
   r += 56 * par[36] * TMath::Power(x[0], 6);
   // r += par[37] * TMath::Power(x[1], 8);
   r += 42 * par[38] * TMath::Power(x[0], 5) * TMath::Power(x[1], 1);
   r += 30 * par[39] * TMath::Power(x[0], 4) * TMath::Power(x[1], 2);
   r += 20 * par[40] * TMath::Power(x[0], 3) * TMath::Power(x[1], 3);
   r += 12 * par[41] * TMath::Power(x[0], 2) * TMath::Power(x[1], 4);
   r += 6 * par[42] * TMath::Power(x[0], 1) * TMath::Power(x[1], 5);
   r += 2 * par[43] * TMath::Power(x[1], 6);
   // r += par[44] * TMath::Power(x[1], 7);
   return r;
}


Double_t CpPolynom2D::Derivate2XDegree9(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree8(x, par);;
   // x^9 y^9 x^8*y x^7*y^2 x^6*y^3 x^5*y^4 x^4*y^5 x^3*y^6 x^2*y^7 x*y^8
   r += 72 * par[45] * TMath::Power(x[0], 7);
   // r += par[46] * TMath::Power(x[1], 9);
   r += 56 * par[47] * TMath::Power(x[0], 6) * TMath::Power(x[1], 1);
   r += 42 * par[48] * TMath::Power(x[0], 5) * TMath::Power(x[1], 2);
   r += 30 * par[49] * TMath::Power(x[0], 4) * TMath::Power(x[1], 3);
   r += 20 * par[50] * TMath::Power(x[0], 3) * TMath::Power(x[1], 4);
   r += 12 * par[51] * TMath::Power(x[0], 2) * TMath::Power(x[1], 5);
   r += 6 * par[52] * TMath::Power(x[0], 1) * TMath::Power(x[1], 6);
   r += 2 * par[53] * TMath::Power(x[1], 7);
  //  r += par[54] * TMath::Power(x[1], 8);
   return r;
}
Double_t CpPolynom2D::Derivate2XDegree10(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2XDegree9(x, par);;
   // x^10 y^10 x^9*y x^8*y^2 x^7*y^3 x^6*y^4 x^5*y^5 x^4*y^6 x^3*y^7 x^2*y^8 x*y^9
   r += 90 * par[55] * TMath::Power(x[0], 8);
   // r += par[56] * TMath::Power(x[1], 10);
   r += 72 * par[57] * TMath::Power(x[0], 7) * TMath::Power(x[1], 1);
   r += 56 * par[58] * TMath::Power(x[0], 6) * TMath::Power(x[1], 2);
   r += 42 * par[59] * TMath::Power(x[0], 5) * TMath::Power(x[1], 3);
   r += 30 * par[60] * TMath::Power(x[0], 4) * TMath::Power(x[1], 4);
   r += 20 * par[61] * TMath::Power(x[0], 3) * TMath::Power(x[1], 5);
   r += 12 * par[62] * TMath::Power(x[0], 2) * TMath::Power(x[1], 6);
   r += 6 * par[63] * TMath::Power(x[0], 1) * TMath::Power(x[1], 7);
   r += 2 * par[64] * TMath::Power(x[1], 8);
   // r += par[65] * TMath::Power(x[1], 9);
   return r;
}

// 2 Derivacia podla y
Double_t CpPolynom2D::Derivate2YDegree0(Double_t */*x*/, Double_t */*par*/)
{
   return 0;
}


Double_t CpPolynom2D::Derivate2YDegree1(Double_t */*x*/, Double_t */*par*/)
{

   //Double_t r = Derivate2YDegree0(x, par);;
   // r += par[1] * TMath::Power(x[0], 1);
   // r += par[2];
   return 0;
}


Double_t CpPolynom2D::Derivate2YDegree2(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2YDegree1(x, par);
   // x^2 y^2
   // r += par[3] * TMath::Power(x[0], 2);
   r += 2 * par[4];
   // r += par[5] * TMath::Power(x[0], 1);
   return r;
}


Double_t CpPolynom2D::Derivate2YDegree3(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2YDegree2(x, par);
   // x^3 y^3 x^2*y x*y^2 x*y^3
   // r += par[6] * TMath::Power(x[0], 3);
   r += 6 * par[7] * TMath::Power(x[1], 1);
   // r += par[8] * TMath::Power(x[0], 2);
   r += 2 * par[9] * TMath::Power(x[0], 1) ;

   return r;
}

Double_t CpPolynom2D::Derivate2YDegree4(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2YDegree3(x, par);;
   // x^4 y^4 x^3*y x^2*y^2 x*y^3
   // r += par[10] * TMath::Power(x[0], 4);
   r += 12 * par[11] * TMath::Power(x[1], 2);
   // r += par[12] * TMath::Power(x[0], 3);
   r += 2 * par[13] * TMath::Power(x[0], 2) ;
   r += 6 * par[14] * TMath::Power(x[0], 1) * TMath::Power(x[1], 1);
   return r;
}


Double_t CpPolynom2D::Derivate2YDegree5(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2YDegree4(x, par);;
// x^5 y^5 x^4*y x^3*y^2 x^2*y^3 x*y^4
   // r += par[15] * TMath::Power(x[0], 5);
   r += 20 * par[16] * TMath::Power(x[1], 3);
   // r += par[17] * TMath::Power(x[0], 4) ;
   r += 2 * par[18] * TMath::Power(x[0], 3);
   r += 6 * par[19] * TMath::Power(x[0], 2) * TMath::Power(x[1], 1);
   r += 12 * par[20] * TMath::Power(x[0], 1) * TMath::Power(x[1], 2);
   return r;
}

Double_t CpPolynom2D::Derivate2YDegree6(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2YDegree5(x, par);;
   // x^6 y^6 x^5*y x^4*y^2 x^3*y^3 x^2*y^4 x*y^5
   // r += par[21] * TMath::Power(x[0], 6);
   r +=30 * par[22] * TMath::Power(x[1], 4);
   // r += par[23] * TMath::Power(x[0], 5);
   r += 2 * par[24] * TMath::Power(x[0], 4);
   r += 6 * par[25] * TMath::Power(x[0], 3) * TMath::Power(x[1], 1);
   r += 12 * par[26] * TMath::Power(x[0], 2) * TMath::Power(x[1], 2);
   r += 20 * par[27] * TMath::Power(x[0], 1) * TMath::Power(x[1], 3);
   return r;
}

Double_t CpPolynom2D::Derivate2YDegree7(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2YDegree6(x, par);;
   // x^7 y^7 x^6*y x^5*y^2 x^4*y^3 x^3*y^4 x^2*y^5 x*y^6
   // r += par[28] * TMath::Power(x[0], 7);
   r += 42 * par[29] * TMath::Power(x[1], 5);
   // r += par[30] * TMath::Power(x[0], 6) ;
   r += 2 * par[31] * TMath::Power(x[0], 5);
   r += 6 * par[32] * TMath::Power(x[0], 4) * TMath::Power(x[1], 1);
   r += 12 * par[33] * TMath::Power(x[0], 3) * TMath::Power(x[1], 2);
   r += 20 * par[34] * TMath::Power(x[0], 2) * TMath::Power(x[1], 3);
   r += 30 * par[35] * TMath::Power(x[0], 1) * TMath::Power(x[1], 4);
   return r;
}


Double_t CpPolynom2D::Derivate2YDegree8(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2YDegree7(x, par);;
   // x^8 y^8 x^7*y x^6*y^2 x^5*y^3 x^4*y^4 x^3*y^5 x^2*y^6 x*y^7
   // r += par[36] * TMath::Power(x[0], 8);
   r += 56 * par[37] * TMath::Power(x[1], 6);
   // r += par[38] * TMath::Power(x[0], 7) ;
   r += 2 * par[39] * TMath::Power(x[0], 6);
   r += 6 * par[40] * TMath::Power(x[0], 5) * TMath::Power(x[1], 1);
   r += 12 * par[41] * TMath::Power(x[0], 4) * TMath::Power(x[1], 2);
   r += 20 * par[42] * TMath::Power(x[0], 3) * TMath::Power(x[1], 3);
   r += 30 * par[43] * TMath::Power(x[0], 2) * TMath::Power(x[1], 4);
   r += 42 * par[44] * TMath::Power(x[0], 1) * TMath::Power(x[1], 5);
   return r;
}


Double_t CpPolynom2D::Derivate2YDegree9(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2YDegree8(x, par);;
   // x^9 y^9 x^8*y x^7*y^2 x^6*y^3 x^5*y^4 x^4*y^5 x^3*y^6 x^2*y^7 x*y^8
   // r += par[45] * TMath::Power(x[0], 9);
   r += 72 * par[46] * TMath::Power(x[1], 7);
   // r += par[47] * TMath::Power(x[0], 8) ;
   r += 2 * par[48] * TMath::Power(x[0], 7) ;
   r += 6 * par[49] * TMath::Power(x[0], 6) * TMath::Power(x[1], 1);
   r += 12 * par[50] * TMath::Power(x[0], 5) * TMath::Power(x[1], 2);
   r += 20 * par[51] * TMath::Power(x[0], 4) * TMath::Power(x[1], 3);
   r += 30 * par[52] * TMath::Power(x[0], 3) * TMath::Power(x[1], 4);
   r += 42 * par[53] * TMath::Power(x[0], 2) * TMath::Power(x[1], 5);
   r += 56 * par[54] * TMath::Power(x[0], 1) * TMath::Power(x[1], 6);
   return r;
}
Double_t CpPolynom2D::Derivate2YDegree10(Double_t *x, Double_t *par)
{
   Double_t r = Derivate2YDegree9(x, par);;
   // x^10 y^10 x^9*y x^8*y^2 x^7*y^3 x^6*y^4 x^5*y^5 x^4*y^6 x^3*y^7 x^2*y^8 x*y^9
   // r += par[55] * TMath::Power(x[0], 10);
   r += 90 * par[56] * TMath::Power(x[1], 8);
   // r += par[57] * TMath::Power(x[0], 9) ;
   r += 2 * par[58] * TMath::Power(x[0], 8);
   r += 6 * par[59] * TMath::Power(x[0], 7) * TMath::Power(x[1], 1);
   r += 12 * par[60] * TMath::Power(x[0], 6) * TMath::Power(x[1], 2);
   r += 20 * par[61] * TMath::Power(x[0], 5) * TMath::Power(x[1], 3);
   r += 30 * par[62] * TMath::Power(x[0], 4) * TMath::Power(x[1], 4);
   r += 42 * par[63] * TMath::Power(x[0], 3) * TMath::Power(x[1], 5);
   r += 56 * par[64] * TMath::Power(x[0], 2) * TMath::Power(x[1], 6);
   r += 72 * par[65] * TMath::Power(x[0], 1) * TMath::Power(x[1], 7);
   return r;
}